import classNames from "classnames"
import * as _ from "lodash"
import * as React from "react"
import { Dispatch, HTMLAttributes, SetStateAction, useEffect, useRef, useState } from "react"
import Icon from "../../icon"
import Button from "../button"
import Flex from "../flex"
import NavBar from "../navbar"
import { prefixClassName } from "../style"
import Typography from "../typography"
import WhiteSpace from "../white-space"
import "./index.scss"

interface ItemNumberProps extends HTMLAttributes<HTMLSpanElement> {
}

function ItemNumber(props: ItemNumberProps) {
  const { onClick, children } = props
  return (<span
    onClick={onClick}
    className={classNames(prefixClassName("captcha-number-item"),
      {
        [prefixClassName("captcha-number-item-active")]: !_.isUndefined(children),
      })}>{children}</span>)
}

function useCountdown(): [number, Dispatch<SetStateAction<number>>] {
  const [countdown, setCountdown] = useState(0)
  useEffect(() => {
    if (countdown > 0) {
      const timer = setTimeout(() => {
        setCountdown(value => value - 1)
      }, 1000)
      return () => clearTimeout(timer)
    }
    return () => {
    }
  }, [countdown])
  return [countdown, setCountdown]
}

interface CaptchaProps {
  mobile: string
  onClose: () => void
  onChange: (code: string) => void
  retrieveDuration?: number
  onRetrieve?: () => void
}

export default function Captcha(props: CaptchaProps) {
  const { mobile, retrieveDuration = 60, onClose, onRetrieve, onChange } = props
  const [codes, setCodes] = useState([] as string[])
  const [codesChanged, setCodesChanged] = useState(false)
  const inputRef = useRef<HTMLInputElement>(null)
  const [countdown, setCountdown] = useCountdown()

  function setValueToCodes(value: string) {
    if (codesChanged) {
      return
    }
    const values = _.slice(_.split(value, ""), 0, 6)
    setCodes(_.concat(values))
    if (_.size(values) === 6) {
      setCodesChanged(true)
      onChange(_.join(values, ""))
    } else {
      setCodes(_.concat(values, [""]))
    }
  }

  useEffect(() => {
    setCountdown(retrieveDuration)
  }, [retrieveDuration, setCountdown])

  function handleRetrieving() {
    if (_.isFunction(onRetrieve) && countdown === 0) {
      setCountdown(retrieveDuration)
      onRetrieve()
    }
  }

  return (
    <div className={prefixClassName("captcha")}>
      <NavBar left={<Icon type="left" onClick={onClose}/>}/>
      <div className={prefixClassName("captcha-content")}>
        <Typography.Title level={2} className={prefixClassName("captcha-title")}>输入验证码</Typography.Title>
        <Typography.Text type="secondary">请输入 {mobile} 收到的验证码</Typography.Text>
        <Flex alignItems="center" justifyContent="space-between"
              className={prefixClassName("captcha-numbers")}>
          {_.map(_.range(6), index =>
            <ItemNumber key={index} onClick={() => {
              inputRef.current?.focus()
            }} children={codes[index]}/>)}
        </Flex>
        <input type="number" ref={inputRef} value={_.join(codes, "")}
               onChange={event => setValueToCodes(event.target.value)}/>
        <WhiteSpace size="lg"/>
        <Flex justifyContent="flex-start">
          <Button className={prefixClassName("retrieve-captcha")} type="link"
                  disabled={countdown !== 0}
                  onClick={handleRetrieving}>{countdown === 0 ? "获得验证码" : `重新发送(${countdown})`}</Button>

        </Flex>
      </div>
    </div>
  )
}
